<template>
  <el-container v-if="userinfo">
    <el-aside width="20em" class="user-info">
      <div>
        <el-upload
          class="avatar-uploader"
          :show-file-list="false"
          action=""
          :before-upload="beforeAvatarUpload"
          :http-request="upload"
          :disabled="isVisitor"
        >
          <img v-if="userinfo.avatar" :src="userinfo.avatar" class="avatar" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
        <el-row
          v-if="isVisitor"
          type="flex"
          style="margin-left: 1em; margin-bottom: 1em"
        >
          <el-button
            v-if="$store.state.login"
            :type="followed ? 'plain' : 'primary'"
            style="width: 13em"
            @click="follow(userinfo.id)"
            >{{ followed ? "取消关注" : "关注" }}</el-button
          >
        </el-row>
        <div>
          <el-collapse accordion v-model="activeNames">
            <el-collapse-item name="nickname" :disabled="isVisitor">
              <template slot="title">
                昵称：{{ userinfo.nickname | nicknameEllipsis }}
              </template>
              <div>
                <el-form
                  :inline="true"
                  ref="nicknameForm"
                  :rules="nicknameRules"
                  :model="nicknameForm"
                >
                  <el-form-item label="新的昵称" prop="nickname"
                    ><el-input v-model="nicknameForm.nickname"></el-input
                  ></el-form-item>
                  <el-form-item
                    ><el-button @click="changeNickname" type="primary"
                      >提交</el-button
                    ></el-form-item
                  >
                </el-form>
              </div>
            </el-collapse-item>

            <el-collapse-item name="gender" :disabled="isVisitor">
              <template slot="title">
                性别：<i :class="gender_icon_class"></i>
              </template>
              <div>
                <el-form
                  :inline="true"
                  ref="genderForm"
                  :model="genderForm"
                  :rules="genderRules"
                >
                  <el-form-item label="修改性别">
                    <el-radio v-model="genderForm.gender" label="1"
                      ><i class="fa fa-mars">(男)</i></el-radio
                    >
                    <el-radio v-model="genderForm.gender" label="0"
                      ><i class="fa fa-venus">(女)</i></el-radio
                    >
                    <el-radio v-model="genderForm.gender" label="-1"
                      ><i class="fa fa-genderless">(保密)</i></el-radio
                    >
                  </el-form-item>
                  <el-form-item
                    ><el-button @click="changeGender" type="primary"
                      >提交</el-button
                    ></el-form-item
                  >
                </el-form>
              </div>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div></el-aside
    >
    <el-container>
      <el-main
        ><el-form
          :model="articleForm"
          ref="articleForm"
          :rules="articleRules"
          v-if="!isVisitor"
          style="margin-bottom: 1em"
        >
          <el-form-item prop="article">
            <el-input
              type="textarea"
              placeholder="说点儿啥..."
              v-model="articleForm.article"
              maxlength="100"
              show-word-limit
              autosize
            ></el-input>
          </el-form-item>
          <el-button type="primary" size="mini" @click="createAnArticle"
            >发布</el-button
          >
          <el-button @click="resetArticleForm" size="mini">清空</el-button>
        </el-form>
        <el-tabs v-model="activeName" @tab-click="handleClick">
          <el-tab-pane label="已发表" name="articles" :lazy="true">
            <ArticleList
              :url="articleListUrl"
              v-if="articleListUrl"
              :key="articleListKey + articleListUrl + refreshKey1"
              @pageChanged="handleArticlePageChanged"
              :currentPage="currentArticlePage"
              :deletable="!isVisitor"
              @deleteArticle="setArticleListKey"
            ></ArticleList>
          </el-tab-pane>
          <el-tab-pane label="已收藏" name="likes" :lazy="true">
            <ArticleList
              :url="likeListUrl"
              v-if="likeListUrl"
              :key="unlikedArticleKey + likeListUrl + refreshKey2"
              @pageChanged="handleLikePageChanged"
              :currentPage="currentLikePage"
              :unlikable="!isVisitor"
              @updateArticle="setUnlikedArticleKey"
            ></ArticleList>
          </el-tab-pane>
          <el-tab-pane label="关注" name="followers" :lazy="true">
            <UserList
              userType="followees"
              :userinfoId="userinfo.id"
              :editable="!isVisitor"
              :key="unfollowedKey + refreshKey3"
              @updateUnfollowKey="updateUnfollowKey"
              @unfollow="unfollow"
            ></UserList>
          </el-tab-pane>
          <el-tab-pane label="粉丝" name="followees" :lazy="true">
            <UserList
              userType="followers"
              :userinfoId="userinfo.id"
              :editable="!isVisitor"
              :key="removeFollowerKey + refreshKey4"
              @removeFollowers="updateRemoveFollowerKey"
            ></UserList
          ></el-tab-pane>
        </el-tabs>
      </el-main>
    </el-container>
  </el-container>
</template>

<script>
import UserList from "@/components/UserList.vue";
import ArticleList from "@/components/ArticleList.vue";

export default {
  data() {
    var checkArticle = (rule, value, callback) => {
      if (value.replace(/\n+/g, "") == "") {
        return callback(new Error("不能为空"));
      } else {
        callback();
      }
    };
    return {
      userinfo: null,
      articleListUrl: "",
      likeListUrl: "",
      currentArticlePage: 1,
      currentLikePage: 1,
      activeName: "articles",
      activeNames: "",
      nicknameRules: {
        nickname: [{ required: true, message: "不能为空", trigger: "blur" }],
      },
      nicknameForm: { nickname: "" },
      genderRules: {
        gender: [{ required: true, message: "不能为空", trigger: "blur" }],
      },
      genderForm: { gender: "" },
      articleListKey: "",
      unlikedArticleKey: "",
      unfollowedKey: "",
      removeFollowerKey: "",
      refreshKey1: "",
      refreshKey2: "",
      refreshKey3: "",
      refreshKey4: "",
      articleForm: {
        article: "",
      },
      articleRules: {
        article: [
          { required: true, message: "不能为空", trigger: "blur" },
          { validator: checkArticle, trigger: "blur" },
        ],
      },
    };
  },
  components: {
    UserList,
    ArticleList,
  },
  mounted() {
    this.get_user();
  },
  computed: {
    gender_icon_class() {
      switch (this.userinfo.gender) {
        case "0":
        case 0:
          return "fa fa-venus fa-lg ";
        case "1":
        case 1:
          return "fa fa-mars fa-lg";
        case "-1":
        case -1:
          return "fa fa-genderless fa-lg";
        default:
          return "";
      }
    },
    isVisitor() {
      return localStorage.id != this.userinfo.id || !this.$store.state.login;
    },
    followed() {
      const visitorId = parseInt(localStorage.getItem("info"));
      return this.userinfo.followers.indexOf(visitorId) != -1;
    },
  },
  methods: {
    get_user() {
      const { id } = this.$route.params;
      this.$http.get(`userinfos/${id}/`).then((res) => {
        this.userinfo = res.data;
        this.articleListUrl = `articles/?author=${this.userinfo.id}`;
        this.likeListUrl = `articles/?liked_by=${this.userinfo.id}`;
        if (this.$route.params.fromAuth) {
          this.$store.commit("setAvatar", this.userinfo.avatar);
        }
      });
    },
    beforeAvatarUpload(file) {
      const isJPG = file.type === "image/jpeg";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPG) {
        this.$message.error("上传头像图片只能是 JPG 格式!");
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isJPG && isLt2M;
    },
    upload(file) {
      const uploadData = new FormData();
      uploadData.append("avatar", file.file);
      this.$http
        .patch(`userinfos/${this.userinfo.id}/`, uploadData)
        .then((res) => {
          this.userinfo.avatar = res.data.avatar;
          this.$store.commit("setAvatar", this.userinfo.avatar);
        });
    },
    changeNickname() {
      this.$refs.nicknameForm.validate((valid) => {
        if (valid) {
          this.$http
            .patch(`userinfos/${this.userinfo.id}/`, {
              nickname: this.nicknameForm.nickname,
            })
            .then((res) => {
              this.userinfo = res.data;
              this.activeNames = "";
            });
        } else {
          return false;
        }
      });
    },
    changeGender() {
      this.$refs.genderForm.validate((valid) => {
        if (valid) {
          this.$http
            .patch(`userinfos/${this.userinfo.id}/`, {
              gender: this.genderForm.gender,
            })
            .then((res) => {
              this.userinfo = res.data;
              this.activeNames = "";
            });
        } else {
          return false;
        }
      });
    },
    resetArticleForm() {
      this.$refs.articleForm.resetFields();
    },
    createAnArticle() {
      this.$refs.articleForm.validate((valid) => {
        if (valid) {
          this.createAnArticleReq();
        } else {
          return false;
        }
      });
    },
    createAnArticleReq() {
      this.articleForm.article = this.articleForm.article.replace(/\n+/g, "\n");
      this.$http
        .post("articles/", { content: this.articleForm.article })
        .then((res) => {
          this.articleListKey = res.data.id;
          this.articleForm.article = "";
        });
    },
    handleArticlePageChanged(currentPage) {
      const pos = this.articleListUrl.search("[Pp][Aa][Gg][Ee]");
      const questionPos = this.articleListUrl.indexOf("?");
      const joinChar = questionPos == -1 ? "?" : "&";
      if (pos == -1) {
        this.articleListUrl += `${joinChar}page=${currentPage}`;
      } else {
        const regex = /(page=)\d+/;
        this.articleListUrl = this.articleListUrl.replace(
          regex,
          `$1${currentPage}`
        );
      }
      this.currentArticlePage = currentPage;
    },

    handleLikePageChanged(currentPage) {
      const pos = this.likeListUrl.search("[Pp][Aa][Gg][Ee]");
      const questionPos = this.likeListUrl.indexOf("?");
      const joinChar = questionPos == -1 ? "?" : "&";
      if (pos == -1) {
        this.likeListUrl += `${joinChar}page=${currentPage}`;
      } else {
        const regex = /(page=)\d+/;
        this.likeListUrl = this.likeListUrl.replace(regex, `$1${currentPage}`);
      }
      this.currentLikePage = currentPage;
    },
    setUnlikedArticleKey(val) {
      this.unlikedArticleKey = val;
    },
    setArticleListKey(val) {
      this.articleListKey = val;
    },
    follow(infoId) {
      this.$http.post(`userinfos/${infoId}/follow/`).then((res) => {
        if (this.followed) {
          this.$message({
            message: "取消关注成功",
            type: "success",
            duration: 1000,
          });
        } else {
          this.$message({
            message: "关注成功",
            type: "success",
            duration: 1000,
          });
        }
        this.userinfo = res.data;
      });
    },
    unfollow(infoId) {
      this.$http.post(`userinfos/${infoId}/follow/`).then((res) => {
        this.$message({
          message: "取消关注成功",
          type: "success",
          duration: 1000,
        });
        this.unfollowedKey = infoId;
      });
    },
    updateUnfollowKey(key) {
      this.unfollowedKey = key;
    },
    updateRemoveFollowerKey(key) {
      this.removeFollowerKey = key;
    },
    // refresh component when clicked
    handleClick(tab) {
      switch (tab.name) {
        case "articles": {
          this.refreshKey1 = Date.now();
          break;
        }
        case "likes": {
          this.refreshKey2 = Date.now();
          break;
        }
        case "followers": {
          this.refreshKey3 = Date.now();
          break;
        }
        case "followees": {
          this.refreshKey4 = Date.now();
          break;
        }
      }
    },
  },
};
</script>

<style scoped>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  background-color: lightgray;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 10em;
  color: #8c939d;
  width: 1em;
  height: 1em;
  line-height: 1em;
  text-align: center;
}
.avatar {
  width: 13em;
  height: 13em;
  display: block;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  border: white solid 0.5em;
  margin-bottom: 1em;
  border-radius: 0.5em;
}
.user-info {
  margin: 1em;
  overflow: hidden;
  border-right: lightblue 1px solid;
}
</style>
